﻿using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Text;
using Nemerle.Utility;
using Nemerle.Compiler.Parsetree;
using Nemerle.Compiler.Typedtree;
using NRails.Macros.Model;

using System.Web.Mvc;

using System;
using System.Collections.Generic;
using System.Linq;

namespace NRails.Macros
{
  [Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeTypedMembers, Nemerle.MacroTargets.Class,
                     Inherited = false)]
  /// <summary>
  /// Generates .
  /// </summary>
  public macro DbUsage(t : TypeBuilder)
  {
    DbUsageImpl.InjectManager(t);
  }
  
  internal module DbUsageImpl
  {
      public InjectManager(t : TypeBuilder) : void
      {
          def managerType = DatabaseManagerImpl.GetDbType(t.Manager);
          
          when (managerType == null)
            Message.FatalError("Database manager class not registred");

          def managerType = PExpr.FromQualifiedIdentifier(t.Manager, managerType.FullName);
          
          t.Define(<[decl: mutable _dbHolder : $managerType; ]>);
          t.Define(<[decl: protected override OnResultExecuted(ctx : ResultExecutedContext) : void
                {
                    base.OnResultExecuted(ctx);
                    
                    when (_dbHolder != null)
                    {
                        _dbHolder.Dispose();
                        _dbHolder = null;
                    }
                }
          ]>);
          t.Define(<[decl: protected db : $managerType
                {
                    get 
                    {
                        when (_dbHolder == null)
                          _dbHolder = $managerType();

                        _dbHolder;
                    }
                }
          ]>);
      }
  }
}
